<?php
namespace PsiFramework\Classes\Util\Parameters;

import("Classes.Util.Parameters.Parameters");
import("Classes.Util.Parameters.Object.AttributeParameters");
import("Classes.Util.Parameters.Object.Operation");
import("Classes.Util.Parameters.Object.Trigger");
import("Classes.Model.ModelInterface.IPrimitiveObject");
import("Classes.Util.Manager.ObjectManager");
import("Classes.Util.Database.Query.SqlType");

use \PsiFramework\Classes\Util\Parameters\Parameters;
use \PsiFramework\Classes\Util\Parameters\DAO\ObjectParametersDAO;
use \PsiFramework\Classes\Util\Parameters\Object\AttributeParameters;
use \PsiFramework\Classes\Util\Parameters\Object\Operation;
use \PsiFramework\Classes\Util\Parameters\Object\Trigger;
use \PsiFramework\Classes\Model\ModelInterface\IPrimitiveObject;
use \PsiFramework\Classes\Util\Manager\ObjectManager;
use \PsiFramework\Classes\Util\Database\Query\SqlType;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The ObjectParameters class is the class to manage object parameters
 *
 * @package Util.Parameters
 */
class ObjectParameters extends Parameters implements IPrimitiveObject
{

    protected /*string*/    $_name ;
    protected /*string*/    $_class ;
    protected /*string*/    $_dao ;
    protected /*string*/    $_table ;
    protected /*string*/    $_schema ;
    protected /*bool*/      $_useJoin ;
    protected /*string*/    $_searchService ;
    protected /*array*/     $_primaryKey ;
    protected /*Trigger[]*/ $_triggers ;
    protected /*Operation*/ $_constructionOperation;
    protected /*boolean*/   $_view ;

    public function __construct(
        /*string*/    $name=null,
        /*string*/    $class=null,
        /*string*/    $dao=null,
        /*string*/    $table=null,
        /*string*/    $schema=null,
        /*array*/     $parameters=null,
        /*bool*/      $useJoin=false,
        /*string*/    $searchService=null,
        Operation     $constructionOperation=null,
        /*Trigger[]*/ $triggers=array()
    )
    {
        parent::__construct($parameters);
        $this->_name = $name ;
        $this->_class = $class ;
        $this->_dao = $dao ;
        $this->_table = $table ;
        $this->_view = false ;
        $this->_schema = $schema ;
        $this->_useJoin = $useJoin ;
        $this->_searchService = $searchService;
        $this->_triggers = $triggers ;
        $this->_constructionOperation = $constructionOperation ;

        if (!is_null($parameters)) {
            $pk = array();
            foreach ($parameters as $parameter) {
                if ($parameter->primaryKey) {
                    $pk[] = $parameter ;
                }
            }
            if (count($pk)>0) {
                $this->_primaryKey = $pk ;
            } else {
                $this->_primaryKey = null ;
            }
        } else {
            $this->_primaryKey = null ;
        }
    }

    public static function getTableName($string)
    {
        return preg_replace(
            "/[^a-zA-Z0-9\s]/",
            "",
            strtolower(
                str_replace(
                    ' ',
                    '_',
                    $string
                )
            )
        );
    }

    public function getName()
    {
        return $this->_name ;
    }

    public function getClass()
    {
        return $this->_class ;
    }

    public function getDAO()
    {
        return $this->_dao ;
    }

    public function getTable()
    {
        return $this->_table ;
    }

    public function getSchema()
    {
        return $this->_schema ;
    }

    public function getUseJoin()
    {
        return $this->_useJoin ;
    }
    
    public function getSearchService()
    {
    	return $this->_searchService ;
    }

    public function addParameter(AttributeParameters $parameter)
    {
        $this->_parameters[$parameter->name] = $parameter ;
    }

    public function getPrimaryKey()
    {
        if (!is_null($this->_primaryKey)
            && is_array($this->_primaryKey)
            && count($this->_primaryKey)>0
        ) {
            return $this->_primaryKey ;
        }

        $pk = array();
        foreach ($this->_parameters as $parameter) {
            if ($parameter->primaryKey) {
                $pk[] = $parameter ;
            }
        }
        
        if (count($pk)>0) {
            $this->_primaryKey = $pk ;
        }
        
        return $this->_primaryKey ;
    }

    public function getTriggers(/*string*/ $type=null)
    {
        if (!isNullOrEmptyString($type)) {
            if (array_key_exists($type, $this->_triggers)) {
                return $this->_triggers[$type] ;
            } else {
                return null ;
            }
        } else {
            return $this->_triggers ;
        }
    }

    public function setTriggers(/*Trigger[]*/ $triggers)
    {
        $this->_triggers = $triggers ;
    }

    public function addTrigger(Trigger $trigger)
    {
        if (!array_key_exists($trigger->getType(), $this->_triggers)) {
            $this->_triggers[$trigger->getType()] = array();
        }
        $this->_triggers[$trigger->getType()][] = $trigger ;
    }

    public function getConstructionOperation()
    {
        return $this->_constructionOperation ;
    }

    public function setConstructionOperation(
        Operation $constructionOperation
    )
    {
        $this->_constructionOperation = $constructionOperation ;
    }

    public function isView()
    {
        return $this->_view ;
    }

    public function setView(/*bool*/ $view)
    {
        $this->_view = $view ;
    }

    public function toString()
    {
        return $this->_name ;
    }

    public function serialize(/*bool*/ $asText=true)
    {
        $xml = ObjectParametersDAO::getObjectParametersAsXml($this);
        if ($asText) {
            return $xml->saveXML();
        } else {
            return $xml ;
        }
    }

    public function unserialize(/*string*/ $text)
    {
        //Meilleure gestion ?
        $xml = ObjectParametersDAO::getXMLStringRoot($text);
        if (!is_null($xml)) {
            $op = ObjectParametersDAO::readObject($xml);

            $this->_parameters = $op->getParameters();
            $this->_name = $op->getName();
            $this->_class = $op->getClass();
            $this->_dao = $op->getDAO();
            $this->_table = $op->getTable();
            $this->_view = $op->isView();
            $this->_schema = $op->getSchema();
            $this->_useJoin = $op->getUseJoin();
            $this->_triggers = $op->getTriggers();
            $this->_constructionOperation = $op->getConstructionOperation();
            $this->_primaryKey = $op->getPrimaryKey();
        }
    }

    public static function getSqlType()
    {
        return SqlType::$text ;
    }

}
